#pragma once

#include "vcclr.h"
#include <berkelium\berkelium.hpp>
#include <berkelium\window.hpp>
#include <berkelium\windowdelegate.hpp>

#include "WindowWrapper.h"

using namespace Berkelium;
using namespace System::Collections::Generic;
using namespace System::Drawing;

namespace BerkeliumDotNet
{
	ref class Window;

	public ref class WindowDelegate abstract
	{
	public:
		virtual void OnAddressBarChanged(Window^ window, String^ newUrl) {};
		virtual void OnStartLoading(Window^ window, String^ newUrl) {};
		virtual void OnLoad(Window^ window) {};
		virtual void OnLoadError(Window^ window, String^ error) {};
		virtual void OnResponsive(Window^ window) {};
		virtual void OnUnresponsive(Window^ window) {};
		virtual void OnPaint(Window^ window, IntPtr bitmapIn,
			Rectangle bitmapRect, int dx, int dy, Rectangle scrollRect) {};
		virtual void OnBeforeUnload(Window^ window, bool% proceed) {};
		virtual void OnCancelUnload(Window^ window) {};
		virtual void OnCrashed(Window^ window) {};
		virtual void OnCreatedWindow(Window^ window, Window^ newWindow) {};
		virtual void OnChromeSend(Window^ window, String^ message,
			String^ contents, int numContents) {};
		virtual void OnPaintPluginTexture(Window^ window, IntPtr sourceGLTexture,
			List<Rectangle>^ sourceRects, Rectangle destinationRect) {};

		virtual void OnWidgetCreated(Window^ window, Widget^ newWidget, int zIndex) {};
		virtual void OnWidgetDestroyed(Window^ window, Widget^ newWidget) {};
		virtual void OnWidgetResize(Window^ window, Widget^ widget, int newWidth, int newHeight) {};
		virtual void OnWidgetMove(Window^ window, Widget^ widget, int newX, int newY) {};
		virtual void OnWidgetPaint(Window^ window, Widget^ widget, IntPtr sourceBuffer,
			Rectangle rect, int dx, int dy, Rectangle scrollRect) {};
	};

	class WindowDelegateWrapper : public Berkelium::WindowDelegate
	{
    private:
		gcroot<BerkeliumDotNet::Window^> _window;

	public:
		WindowDelegateWrapper(Window^ window);

		void onAddressBarChanged(Berkelium::Window* win, const char* newURL, size_t newURLLength);
		void onStartLoading(Berkelium::Window* win, const char* newURL, size_t newURLLength);
		void onLoad(Berkelium::Window* win);
		void onLoadError(Berkelium::Window* win, const char* error, size_t errorLength);
		void onResponsive(Berkelium::Window* win);
		void onUnresponsive(Berkelium::Window* win);
		void onPaint(Berkelium::Window* wini, const unsigned char* bitmap_in,
			const Rect &bitmap_rect, int dx, int dy, const Rect &scroll_rect);
		void onBeforeUnload(Berkelium::Window* win, bool* proceed);
		void onCancelUnload(Berkelium::Window* win);
		void onCrashed(Berkelium::Window* win);
		void onCreatedWindow(Berkelium::Window* win, Berkelium::Window* newWindow);
		void onChromeSend(Berkelium::Window* win, WindowDelegate::Data message,
			const WindowDelegate::Data* contents, size_t numContents);
		void onPaintPluginTexture(Berkelium::Window* win, void* sourceGLTexture,
			const std::vector<Rect> srcRects, // relative to destRect
			const Rect &destRect);

		void onWidgetCreated(Berkelium::Window* win, Berkelium::Widget* newWidget, int zIndex);
		void onWidgetDestroyed(Berkelium::Window* win, Berkelium::Widget* newWidget);
		void onWidgetResize(Berkelium::Window* win, Berkelium::Widget* wid, int newWidth, int newHeight);
		void onWidgetMove(Berkelium::Window* win, Berkelium::Widget* wid, int newX, int newY);
		void onWidgetPaint(Berkelium::Window* win, Berkelium::Widget* wid, const unsigned char* sourceBuffer,
			const Rect &rect, int dx, int dy, const Rect &scrollRect);
	};
}
